package com.yanqu.road.server.manger.activity.ghost;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.ghost.config.GhostBossConfig;
import com.yanqu.road.entity.activity.ghost.config.GhostBoxConfig;
import com.yanqu.road.entity.activity.ghost.config.GhostConfig;
import com.yanqu.road.entity.activity.ghost.config.GhostDisperseConfig;
import com.yanqu.road.entity.activity.ghost.config.GhostGuessConfig;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.config.skill.SkillUpgradeInfo;
import com.yanqu.road.entity.enums.eActivityConfigType;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.logic.bussiness.activity.GhostActivityBusiness;
import com.yanqu.road.logic.bussiness.servercenter.ServerBussiness;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ghost.GhostModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.config.SkillMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.utils.LocalDateTimeHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GhostMgr extends TempMgr {

    private static GhostConfig ghostConfig;

    private static int avgOpenDay = 0;

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    public static void reloadActivityData() {
        getLogger().info("reload Ghost Activity start");
        // 活动信息 activityInfo
        List<ActivityInfo> openActivityInfoList = NormalActivityMgr.getOpenActivityInfoList(eActivityType.GhostActivity.getValue());
        if (openActivityInfoList.size() == 0) {
            ghostConfig = null;
            getLogger().info("no ShuiHu Activity in show time");
            return;
        }
        ActivityInfo activityInfo = openActivityInfoList.get(0);

        int activityId = activityInfo.getActivityId();
        List<Integer> activityIdList = new ArrayList<>();
        activityIdList.add(activityId);

        GhostConfig tmpConfig = new GhostConfig();
        tmpConfig.setActivityId(activityId);
        tmpConfig.setActivityInfo(activityInfo);

        // boss配置
        List<GhostBossConfig> bossConfigList = GhostActivityBusiness.getGhostBossConfigList(activityId);
        tmpConfig.setBossConfigList(bossConfigList);

        // 其他配置
        Map<String, ActivityConfig> activityConfigMap = NormalActivityMgr.getActivityConfigMap(activityId);

        String energyConfig = activityConfigMap.get(eActivityConfigType.GHOST_ENERGY_PARAM.getName()).getValue();
        tmpConfig.setMaxEnergy(Integer.valueOf(energyConfig.split(";")[0]));
        tmpConfig.setEnergyRecoveryTime(1000 * Long.valueOf(energyConfig.split(";")[1]));

        List<Integer> buyEnergyConfig = activityConfigMap.get(eActivityConfigType.GHOST_ENERGY_BUY_PARAM.getName()).getIntListValue(";");
        tmpConfig.setBuyEnergyBaseIngots(buyEnergyConfig.get(0));
        tmpConfig.setBuyEnergyIncrIngots(buyEnergyConfig.get(1));
        tmpConfig.setBuyEnergyGetCount(buyEnergyConfig.get(2));
        tmpConfig.setOnceEnergyBuyTimes(buyEnergyConfig.get(3));

        tmpConfig.setExploreGetTokenCount(activityConfigMap.get(eActivityConfigType.GHOST_EXPLORE_GET_TOKEN_COUNT.getName()).getIntValue());

        List<Integer> newsConfig = activityConfigMap.get(eActivityConfigType.GHOST_UNION_NEWS_COUNT.getName()).getIntListValue(";");
        tmpConfig.setMaxAliveNewsCount(newsConfig.get(0));
        tmpConfig.setMaxDeadNewsCount(newsConfig.get(1));

        tmpConfig.setEventWeightList(activityConfigMap.get(eActivityConfigType.GHOST_EVENT_WEIGHT_PARAM.getName()).getIntListValue(";"));

        tmpConfig.setFreeAttackTimes(activityConfigMap.get(eActivityConfigType.GHOST_FREE_ATTACK_TIMES.getName()).getIntValue());

        tmpConfig.setFreeAttackGetTokenCount(activityConfigMap.get(eActivityConfigType.GHOST_FREE_ATTACK_GET_TOKEN_COUNT.getName()).getIntValue());

        tmpConfig.setAttackCostItemCountList(activityConfigMap.get(eActivityConfigType.GHOST_ATTACK_COST_ITEM_COUNT.getName()).getIntListValue(";"));

        tmpConfig.setAttackCostItemId(activityConfigMap.get(eActivityConfigType.GHOST_ATTACK_COST_ITEM_ID.getName()).getIntValue());

        tmpConfig.setAttackCostToTokenCoefficient(activityConfigMap.get(eActivityConfigType.GHOST_ATTACK_COST_TO_TOKEN_COEFFICIENT.getName()).getIntValue());

        tmpConfig.setDamageToScoreRatioList(activityConfigMap.get(eActivityConfigType.GHOST_DAMAGE_SCORE_COEFFICIENT.getName()).getIntListValue("\\|"));

        tmpConfig.setBigBossFindReward(activityConfigMap.get(eActivityConfigType.GHOST_BIG_BOSS_FIND_REWARD.getName()).getValue());

        String disperseConfigParam = activityConfigMap.get(eActivityConfigType.GHOST_DISPERSE_REWARD_PARAM.getName()).getValue();
        List<GhostDisperseConfig> disperseConfigList = new ArrayList<>();
        for (String item : StringUtils.stringToStringList(disperseConfigParam, "\\|")) {
            List<String> paramList = StringUtils.stringToStringList(item, ";");
            GhostDisperseConfig disperseConfig = new GhostDisperseConfig();
            disperseConfig.setReward(paramList.get(0));
            disperseConfig.setCount(Integer.valueOf(paramList.get(1)));
            disperseConfig.setWeight(Integer.valueOf(paramList.get(2)));
            disperseConfig.setNotice(Integer.valueOf(paramList.get(3)) == 1);
            disperseConfigList.add(disperseConfig);
        }
        tmpConfig.setDisperseConfigList(disperseConfigList);

        tmpConfig.setDisperseBaseReward(activityConfigMap.get(eActivityConfigType.GHOST_DISPERSE_BASE_REWARD.getName()).getValue());

        String boxConfigParam = activityConfigMap.get(eActivityConfigType.GHOST_BOX_PARAM.getName()).getValue();
        List<GhostBoxConfig> boxConfigList = new ArrayList<>();
        for (String item : StringUtils.stringToStringList(boxConfigParam, "\\|")) {
            List<Integer> paramList = StringUtils.stringToIntegerList(item, ";");
            GhostBoxConfig boxConfig = new GhostBoxConfig();
            boxConfig.setBoxItemId(paramList.get(0));
            boxConfig.setWeight(paramList.get(1));
            boxConfig.setOpenCost(paramList.get(2) == 0 ? "0" : paramList.get(2) + "=1");
            boxConfigList.add(boxConfig);
        }
        tmpConfig.setBoxConfigList(boxConfigList);

        tmpConfig.setGuessCost(activityConfigMap.get(eActivityConfigType.GHOST_GUESS_COST.getName()).getValue());

        List<GhostGuessConfig> guessConfigList = new ArrayList<>();
        String guessConfigParam = activityConfigMap.get(eActivityConfigType.GHOST_GUESS_PARAM.getName()).getValue();
        for (String item : StringUtils.stringToStringList(guessConfigParam, "\\|")) {
            List<Integer> paramList = StringUtils.stringToIntegerList(item, ";");
            GhostGuessConfig guessConfig = new GhostGuessConfig();
            guessConfig.setRealReward(paramList.get(0) + "=1");
            guessConfig.setFakeReward(paramList.get(1) + "=1");
            guessConfigList.add(guessConfig);
        }
        tmpConfig.setGuessConfigList(guessConfigList);

        tmpConfig.setGuessRealRatio(activityConfigMap.get(eActivityConfigType.GHOST_GUESS_REAL_RATIO.getName()).getIntValue());

        tmpConfig.setGuessNpcId(activityConfigMap.get(eActivityConfigType.GHOST_MARKET_GUESS_NPC_ID.getName()).getIntValue());

        tmpConfig.setAttackBuffId(activityConfigMap.get(eActivityConfigType.GHOST_ATTACK_BUFF_ID.getName()).getIntValue());

        tmpConfig.setTokenId(activityConfigMap.get(eActivityConfigType.GHOST_TOKEN_ID.getName()).getIntValue());

        tmpConfig.setScoreId(activityConfigMap.get(eActivityConfigType.GHOST_SCORE_ID.getName()).getIntValue());

        List<Integer> operationTime = activityConfigMap.get(eActivityConfigType.GHOST_OPERATION_TIME_PARAM.getName()).getIntListValue(";");
        tmpConfig.setStartOperationTime(60 * 1000 * operationTime.get(0));
        tmpConfig.setEndOperationTime(60 * 1000 * operationTime.get(1));

        List<Integer> dayList = new ArrayList<>();
        List<Integer> valueList = new ArrayList<>();
        String hpDayParam = activityConfigMap.get(eActivityConfigType.GHOST_HP_DAY_PARAM.getName()).getValue();
        for (String item : StringUtils.stringToStringList(hpDayParam, "\\|")) {
            List<Integer> paramList = StringUtils.stringToIntegerList(item, ";");
            dayList.add(paramList.get(0));
            valueList.add(paramList.get(1));
        }
        tmpConfig.setHpDayList(dayList);
        tmpConfig.setHpValueList(valueList);

        String abilityEnlargeStr = activityConfigMap.get(eActivityConfigType.GHOST_ABILITY_ENLARGE.getName()).getValue();
        String[] arr = abilityEnlargeStr.split("\\|");
        Map<Integer, Integer> abilityEnlargeMap = new HashMap<>();
        for (String s : arr) {
            String[] split = s.split(";");
            if (split.length >= 2) {
                int key = Integer.parseInt(split[0]);
                int value = Integer.parseInt(split[1]);
                abilityEnlargeMap.put(key, value);
            } else if (split.length == 1) {
                abilityEnlargeMap.put(0, Integer.parseInt(split[0]));
            }
        }
        tmpConfig.setAbilityEnlargeMap(abilityEnlargeMap);

        tmpConfig.setDisperseBaseReward2(activityConfigMap.get(eActivityConfigType.GHOST_CLEAN_DISPERSE_BASE_REWARD.getName()).getValue());

        tmpConfig.setFinalKillReward(activityConfigMap.get(eActivityConfigType.GHOST_FINAL_KILL_DISPERSE_REWARD.getName()).getValue());

        String cleanDisperseParam = activityConfigMap.get(eActivityConfigType.GHOST_CLEAN_DISPERSE_REWARD_PARAM.getName()).getValue();
        List<GhostDisperseConfig> tmpList = new ArrayList<>();
        for (String item : StringUtils.stringToStringList(cleanDisperseParam, "\\|")) {
            List<String> paramList = StringUtils.stringToStringList(item, ";");
            GhostDisperseConfig disperseConfig = new GhostDisperseConfig();
            disperseConfig.setReward(paramList.get(0));
            disperseConfig.setCount(Integer.valueOf(paramList.get(1)));
            disperseConfig.setWeight(Integer.valueOf(paramList.get(2)));
            disperseConfig.setNotice(Integer.valueOf(paramList.get(3)) == 1);
            tmpList.add(disperseConfig);
        }
        tmpConfig.setDisperseConfigList2(tmpList);

        tmpConfig.setAttackBuffSwitch(activityConfigMap.get(eActivityConfigType.GHOST_ATTACK_BUFF_SWITCH.getName()).getIntValue());

        tmpConfig.setBigBossStageCount(activityConfigMap.get(eActivityConfigType.GHOST_BIG_BOSS_STAGE_COUNT.getName()).getIntValue());

        List<String> rewardList = new ArrayList<>();
        List<Integer> weightList = new ArrayList<>();
        String stageRewardParam = activityConfigMap.get(eActivityConfigType.GHOST_BIG_BOSS_STAGE_REWARD_PARAM.getName()).getValue();
        for (String item : StringUtils.stringToStringList(stageRewardParam, "\\|")) {
            List<String> stringList = StringUtils.stringToStringList(item, ",");
            rewardList.add(stringList.get(0));
            weightList.add(Integer.valueOf(stringList.get(1)));
        }
        tmpConfig.setBigBossStageRewardList(rewardList);
        tmpConfig.setBigBossStageWeightLis(weightList);

        tmpConfig.setBigBossStageScoreParam(activityConfigMap.get(eActivityConfigType.GHOST_BIG_BOSS_STAGE_REWARD_SCORE_PARAM.getName()).getIntValue());

        List<Integer> yuanBingParam = activityConfigMap.get(eActivityConfigType.GHOST_YUAN_BING_TRIGGER_PARAM.getName()).getIntListValue(";");
        tmpConfig.setYuanBingTriggerEndTime(yuanBingParam.get(0) * 60L * 1000L);
        tmpConfig.setYuanBingTriggerHpPercent(yuanBingParam.get(1));

        String yuanBingCountParam = activityConfigMap.get(eActivityConfigType.GHOST_YUAN_BING_COUNT_PARAM.getName()).getValue();
        List<Integer> typeList = new ArrayList<>();
        List<Integer> countList = new ArrayList<>();
        for (String item : StringUtils.stringToStringList(yuanBingCountParam, ";")) {
            List<Integer> param = StringUtils.stringToIntegerList(item, ",");
            typeList.add(param.get(0));
            countList.add(param.get(1));
        }
        tmpConfig.setYuanBingBossTypeList(typeList);
        tmpConfig.setYuanBingBossCountList(countList);

        List<Integer> refreshParam = activityConfigMap.get(eActivityConfigType.GHOST_REFRESH_TIME_PARAM.getName()).getIntListValue(";");
        List<Long> refreshTimeList = new ArrayList<>();
        for (Integer refreshTime : refreshParam) {
            refreshTimeList.add(refreshTime * 60L * 1000L);
        }
        tmpConfig.setRefreshTimeList(refreshTimeList);

        List<Integer> scoreDayList = new ArrayList<>();
        List<Integer> scoreValueList = new ArrayList<>();
        String scoreDayParam = activityConfigMap.get(eActivityConfigType.GHOST_SCORE_DAY_PARAM.getName()).getValue();
        for (String item : StringUtils.stringToStringList(scoreDayParam, "\\|")) {
            List<Integer> paramList = StringUtils.stringToIntegerList(item, ";");
            scoreDayList.add(paramList.get(0));
            scoreValueList.add(paramList.get(1));
        }
        tmpConfig.setScoreDayList(scoreDayList);
        tmpConfig.setScoreValueList(scoreValueList);

        if (activityConfigMap.containsKey(eActivityConfigType.GHOST_SEARCH_BIG_BOSS_PARAM.getName())) {
            List<Integer> searchBigBossList = activityConfigMap.get(eActivityConfigType.GHOST_SEARCH_BIG_BOSS_PARAM.getName()).getIntListValue(";");
            if (searchBigBossList.get(0) <= 0) {
                throw new RuntimeException("鬼市探索活阎王增加权重的配置有问题 activityId" + activityId);
            }
            tmpConfig.setBigBossAddiTimes(searchBigBossList.get(0));
            tmpConfig.setBigBossAddiWeight(searchBigBossList.get(1));
        }

        //v5.5 自动战斗配置
        if (activityConfigMap.containsKey(eActivityConfigType.GHOST_AUTO_BATTLE.getName())){
            tmpConfig.setAutoBattleLimit(activityConfigMap.get(eActivityConfigType.GHOST_AUTO_BATTLE.getName()).getIntValue());
        } else {
            tmpConfig.setAutoBattleLimit(20);
        }

        // 设置平均开服天数
        avgOpenDay = calAvgOpenDay(tmpConfig);
        // 设置config
        ghostConfig = tmpConfig;

        getLogger().info("reload Ghost Activity finish");

        reloadPlayerData();
    }

    public static int getActivityId() {
        return ghostConfig == null ? 0 : ghostConfig.getActivityId();
    }

    public static ActivityInfo getActivityInfo() {
        return ghostConfig == null ? null : ghostConfig.getActivityInfo();
    }

    public static GhostConfig getGhostConfig() {
        return ghostConfig;
    }

    public static void reloadPlayerData() {
        for (GamePlayer player : GamePlayerMgr.getCopyPlayerMap().values()) {
            player.getModule(GhostModule.class).syncGhostConfig();
            player.getModule(GhostModule.class).initUserData();
        }
    }

    /**
     * 获取技能加成（鬼市百则）
     */
    public static int getAttackBuffAddition(int level) {
        if (ghostConfig == null) {
            return 0;
        }
        SkillInfo skillInfo = SkillMgr.getSkillInfo(ghostConfig.getAttackBuffId());
        if (skillInfo == null) {
            getLogger().error("GhostMgr can not find skill id={}", ghostConfig.getAttackBuffId());
            return 0;
        }
        return SkillMgr.getSkillAddition(skillInfo, level);
    }

    /**
     * 获取升级技能消耗
     */
    public static String getAttackBuffUpgradeCost(int curLevel) {
        if (ghostConfig == null) {
            return null;
        }
        SkillInfo skillInfo = SkillMgr.getSkillInfo(ghostConfig.getAttackBuffId());
        if (skillInfo == null) {
            return null;
        }
        SkillUpgradeInfo skillUpgradeInfo = SkillMgr.getSkillUpgradeInfo(skillInfo.getUpgradeType(0), curLevel);
        if (skillUpgradeInfo == null) {
            return null;
        }
        return skillInfo.getConsumeGoodsId() + "=" + skillUpgradeInfo.getConsumeCount();
    }

    /**
     * 检查用户数据重置
     */
    public static void checkUserData(GamePlayer player) {
        player.getModule(GhostModule.class).checkUserData();
    }

    /**
     * 是否在开放时间内（10-22点）
     */
    public static boolean inOpenTime() {
        if (ghostConfig == null) {
            return false;
        }
        if (!ActivityMgr.activityInTime(ghostConfig.getActivityInfo())) {
            return false;
        }
        long time = System.currentTimeMillis() - LocalDateTimeHelper.getZeroTimeTimeStamp();
        return time > ghostConfig.getStartOperationTime() && time < ghostConfig.getEndOperationTime();
    }

    /**
     * 获取最终boss类型
     */
    public static int getBigBossType() {
        for (GhostBossConfig bossConfig : ghostConfig.getBossConfigList()) {
            if (bossConfig.isBigBoss()) {
                return bossConfig.getBossType();
            }
        }
        return -1;
    }

    /**
     * 计算开服天数（计算击杀积分用）
     */
    public static int calAvgOpenDay(GhostConfig config) {
        if (config != null) {
            BigDecimal totalOpenTime = BigDecimal.ZERO;
            List<Long> serverIdList = config.getActivityInfo().getServerIdList();
            List<ServerInfo> infoList = ServerBussiness.getServerInfoListByServerIdList(serverIdList);
            long activityTime = config.getActivityInfo().getBeginShowTime() * 1000 + config.getStartOperationTime();
            for (ServerInfo serverInfo : infoList) {
                long subTime = activityTime - serverInfo.getOpenTime() * 1000;
                totalOpenTime = totalOpenTime.add(new BigDecimal(subTime <= 0 ? 0 : subTime));
            }
            return totalOpenTime
                    .divide(BigDecimal.valueOf(infoList.size()), 0, BigDecimal.ROUND_UP)
                    .divide(new BigDecimal(DateHelper.DAY_MILLIONS), 0, BigDecimal.ROUND_DOWN)
                    .intValue();
        }
        return 0;
    }

    /**
     * 计算Boss击杀积分（客户端展示用）
     *
     * @param typeList 没有就传null
     * @param hpList   没有就传null
     */
    public static long calBossKillScore(GhostBossConfig config, List<Integer> typeList, List<Long> hpList) {
        if (avgOpenDay == 0) {
            return 0;
        }

        // 获取血量放大系数
        int hpLarge = 1000;
        for (int i = 0; i < ghostConfig.getHpDayList().size(); i++) {
            hpLarge = ghostConfig.getHpValueList().get(i);
            if (avgOpenDay < ghostConfig.getHpDayList().get(i)) {
                break;
            }
        }

        // 有实际血量就用实际血量算
        long hp = -1;
        if (typeList != null && hpList != null) {
            for (int i = 0; i < typeList.size(); i++) {
                if (typeList.get(i) == config.getBossType()) {
                    hp = hpList.get(i);
                    break;
                }
            }
        }

        if (hp == -1) {
            hp = BigDecimal.valueOf(config.getHp()).multiply(BigDecimal.valueOf(hpLarge)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP).longValue();
        }

        return BigDecimal.valueOf(hp)
                .multiply(BigDecimal.valueOf(ghostConfig.getDamageToScoreRatioList().get(0)))
                .multiply(BigDecimal.valueOf(config.getRewardsKill()))
                .multiply(BigDecimal.valueOf(getScoreDayAddition()))
                .divide(BigDecimal.valueOf(ghostConfig.getDamageToScoreRatioList().get(1)), 4, BigDecimal.ROUND_UP)
                .divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP).longValue();
    }

    /**
     * 计算今日上次重置时间
     */
    public static long calLastResetTime() {
        long now = System.currentTimeMillis();
        long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp();

        long lastResetTime = 0;
        for (Long tmpResetTime : ghostConfig.getRefreshTimeList()) {
            long nextResetTime = zeroTime + tmpResetTime;
            if (now < nextResetTime) {
                break;
            } else {
                lastResetTime = nextResetTime;
            }
        }
        return lastResetTime;
    }

    /**
     * 获取开服天数加成积分
     */
    public static int getScoreDayAddition() {
        if (avgOpenDay == 0) {
            getLogger().error("鬼市计算进攻积分，区服没有设置开服天数。");
            return 1;
        }

        // 获取积分放大系数
        int scoreLarge = 1;
        for (int i = 0; i < ghostConfig.getScoreDayList().size(); i++) {
            scoreLarge = ghostConfig.getScoreValueList().get(i);
            if (avgOpenDay < ghostConfig.getScoreDayList().get(i)) {
                break;
            }
        }

        return scoreLarge;
    }
}
